package com.ea.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ea.admin.mapper.AdminAccountMapper;
import com.ea.admin.mapper.AdminDeptPermissionMapper;
import com.ea.admin.mapper.DeptInfoMapper;
import com.ea.admin.pojo.Enum.RoleCode;
import com.ea.admin.pojo.dto.DepartmentDto;
import com.ea.admin.pojo.po.AdminAccount;
import com.ea.admin.pojo.po.AdminDeptPermission;
import com.ea.admin.pojo.po.DeptInfo;
import com.ea.admin.pojo.vo.account.ContactAdminVo;
import com.ea.admin.pojo.vo.department.DepartmentVo;
import com.ea.admin.service.DeptPermissionService;
import com.ea.common.result.BizException;
import com.ea.common.result.ErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DeptPermissionServiceImpl implements DeptPermissionService {
    @Resource
    AdminDeptPermissionMapper adminDeptPermissionMapper;
    @Resource
    AdminAccountMapper adminAccountMapper;
    @Resource
    DeptInfoMapper deptInfoMapper;

    @Override
    public List<DepartmentVo> getDeptPermission(List<Long> companyIdList, Long accountId) {
        int rootLevel = adminDeptPermissionMapper.getMinLevelByAccountId(accountId);
        Long adminRoleId = adminAccountMapper.selectById(accountId).getAdminRoleId();
        // 单位管理员默认所有部门权限
        if(adminRoleId== RoleCode.COMPANY_SUPER_ADMIN.getCode().longValue()||
                adminRoleId== RoleCode.COMPANY_ADMIN.getCode().longValue()) {
            rootLevel=0;
            accountId=1L;
        }
        // 先获得用户管理的所有部门
        List<DepartmentDto> allDept = adminDeptPermissionMapper.
                getAllDeptList(accountId, companyIdList, null);
        List<DepartmentDto> rootDept = new ArrayList<>();
        HashMap<Long, DepartmentDto> map = new HashMap<>();
        for (DepartmentDto departmentDto : allDept) {
            List<DepartmentDto> subDeptList = new ArrayList<>();
            departmentDto.setSubDeptList(subDeptList);

            if (departmentDto.getLevel() == rootLevel) {
                rootDept.add(departmentDto);
            }
            map.put(departmentDto.getDeptId(), departmentDto);
            if (departmentDto.getSupDeptId() != null && map.containsKey(departmentDto.getSupDeptId())) {
                DepartmentDto supDept = map.get(departmentDto.getSupDeptId());
                supDept.getSubDeptList().add(departmentDto);
            }
        }

        return parseDeptDtoToVo(rootDept);
    }

    @Override
    public List<Long> getDepartmentIdList(Long accountId) {
        return deptInfoMapper.getDepartmentIdList(accountId);
    }

    private List<DepartmentVo> parseDeptDtoToVo(List<DepartmentDto> deptDtoList) {
        if (deptDtoList == null) {
            return null;
        }

        List<DepartmentVo> voList = new ArrayList<>();
        for (DepartmentDto deptDto : deptDtoList) {
            DepartmentVo deptVo = new DepartmentVo();
            deptVo.setDeptId(deptDto.getDeptId().toString());
            deptVo.setDeptName(deptDto.getDeptName());
            if (deptDto.getSupDeptId() != null) {
                deptVo.setSupDeptId(deptDto.getSupDeptId().toString());
                deptVo.setSupDeptName(deptDto.getSupDeptName());
            }
            deptVo.setCompanyId(deptDto.getCompanyId().toString());
            deptVo.setCompanyName(deptDto.getCompanyName());
            if (deptDto.getContactAdminId() != null) {
                deptVo.setContactAdminId(deptDto.getContactAdminId().toString());
            }
            deptVo.setContactAdminName(deptDto.getContactAdminName());
            deptVo.setContactAdminPhoneNum(deptDto.getContactAdminPhoneNum());
            deptVo.setSubDeptVoList(parseDeptDtoToVo(
                    deptDto.getSubDeptList()
            ));
            voList.add(deptVo);
        }
        return voList;
    }

    @Override
    public void checkAccountDept(Long accountId, Long deptId) {
        Long adminRoleId = adminAccountMapper.selectById(accountId).getAdminRoleId();
        if (deptId == null) {
            // 如果是超级管理员、单位超管、单位管理员，则可以操作所有部门
            if (adminRoleId != RoleCode.SUPER_ADMIN.getCode().longValue()
                    && adminRoleId != RoleCode.COMPANY_SUPER_ADMIN.getCode().longValue()
                    && adminRoleId != RoleCode.COMPANY_ADMIN.getCode().longValue()) {
                throw new BizException(ErrorCode.USER_PERMISSION_ERROR_ONLY_SUPER_ADMIN);
            }
            return;
        }

        checkDeptPermission(accountId, deptId);

        Integer level = deptInfoMapper.selectById(deptId).getLevel();
        // 检查是否是一级部门 检查管理员角色是否为超级管理员、单位超管、单位管理员
        if (level == 0
                && adminRoleId != RoleCode.SUPER_ADMIN.getCode().longValue()
                && adminRoleId != RoleCode.COMPANY_SUPER_ADMIN.getCode().longValue()
                && adminRoleId != RoleCode.COMPANY_ADMIN.getCode().longValue()) {
            throw new BizException(ErrorCode.USER_PERMISSION_ERROR_ONLY_SUPER_ADMIN_COMPANY_SUPER_AMIN_COMPANY_ADMIN);
        }
        // 不是一级部门，检查角色是否单位超管、单位管理员、部门超管
        else if (level != 0
                && adminRoleId != RoleCode.SUPER_ADMIN.getCode().longValue()
                && adminRoleId != RoleCode.COMPANY_SUPER_ADMIN.getCode().longValue()
                && adminRoleId != RoleCode.COMPANY_ADMIN.getCode().longValue()
                && adminRoleId != RoleCode.DEPT_SUPER_ADMIN.getCode().longValue()) {
            throw new BizException(ErrorCode.USER_PERMISSION_ERROR_ONLY_SUPER_ADMIN_COMPANY_SUPER_AMIN_COMPANY_ADMIN_DEPT_SUPER_ADMIN);
        }
    }

    @Override
    public void addDeptPermission(Long accountId, Long deptId) {
        AdminDeptPermission adminDeptPermission = new AdminDeptPermission();
        adminDeptPermission.setAccountId(accountId);
        adminDeptPermission.setDeptId(deptId);
        adminDeptPermission.setIsDel(0);
        adminDeptPermissionMapper.insert(adminDeptPermission);
    }

    @Override
    public void addDeptPermission(List<Long> accountIdList, Long deptId) {
        List<AdminDeptPermission> adminDeptPermissionList = accountIdList.stream().map(accountId -> {
            AdminDeptPermission adminDeptPermission = new AdminDeptPermission();
            adminDeptPermission.setAccountId(accountId);
            adminDeptPermission.setDeptId(deptId);
            adminDeptPermission.setIsDel(0);
            return adminDeptPermission;
        }).collect(Collectors.toList());
        adminDeptPermissionMapper.insertBatchSomeColumn(adminDeptPermissionList);
    }

    @Override
    public void addDeptPermission(Long accountId, List<Long> deptPermissionList) {
        List<AdminDeptPermission> adminDeptPermissionList = deptPermissionList.stream().map(
                deptId -> {
                    AdminDeptPermission adminDeptPermission = new AdminDeptPermission();
                    adminDeptPermission.setAccountId(accountId);
                    adminDeptPermission.setDeptId(deptId);
                    adminDeptPermission.setIsDel(0);
                    return adminDeptPermission;
                }
        ).collect(Collectors.toList());
        adminDeptPermissionMapper.insertBatchSomeColumn(adminDeptPermissionList);
    }

    @Override
    public void checkContactDept(Long accountId, List<Long> deptPermissionList) {
        LambdaQueryWrapper<DeptInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DeptInfo::getContactAdminId, accountId);
        List<DeptInfo> deptInfoList = deptInfoMapper.selectList(wrapper);
        log.info("deptInfoList:{}", deptInfoList);
        if (deptInfoList == null || deptInfoList.isEmpty()) {
            return;
        }
        List<Long> set = deptInfoList.stream().map(DeptInfo::getDeptId)
                .filter(Objects::nonNull).collect(Collectors.toList());
        if (deptPermissionList == null || deptPermissionList.isEmpty() || !new HashSet<>(deptPermissionList).containsAll(set)) {
            throw new BizException(ErrorCode.USER_PARAM_ERROR_IS_DEPT_CONTACT);
        }
    }

    @Override
    public List<Long> getSubDepartmentIdList(Long accountId, List<Long> companyIdList, List<Long> deptIdList) {
        return adminDeptPermissionMapper.getSubDepartmentIdList(accountId, companyIdList, deptIdList);
    }

    @Override
    public List<Long> getAdminId(Long deptId) {
        LambdaQueryWrapper<DeptInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DeptInfo::getDeptId, deptId)
                .eq(DeptInfo::getIsDel, 0);
        return deptInfoMapper.selectList(wrapper).stream().map(DeptInfo::getContactAdminId).collect(Collectors.toList());
    }

    @Override
    public boolean checkDepartmentExists(Long deptId) {
        LambdaQueryWrapper<DeptInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DeptInfo::getDeptId, deptId)
                .eq(DeptInfo::getIsDel, 0);
        return deptInfoMapper.selectCount(wrapper) > 0;
    }

    @Override
    public void deleteDeptPermissionByAccountId(Long accountId) {
        LambdaQueryWrapper<AdminDeptPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AdminDeptPermission::getAccountId, accountId);
        adminDeptPermissionMapper.delete(wrapper);
    }

    @Override
    public void checkIsDeptContact(Long accountId) {
        LambdaQueryWrapper<DeptInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DeptInfo::getContactAdminId, accountId);
        if (deptInfoMapper.selectCount(wrapper) > 0) {
            throw new BizException(ErrorCode.SYSTEM_RESOURCE_IS_DEPT_CONTACT);
        }
    }

    @Override
    public List<ContactAdminVo> getAllAdminInfoByCompanyIdAndName(Long companyId, String contactName) {
        return adminDeptPermissionMapper.getAllAdminInfoByCompanyIdAndName(companyId, contactName);
    }

    /**
     * 检查部门是否存在以及权限是否正确
     */
    @Override
    public void checkDeptPermission(Long accountId, Long deptId) {
        // 是否是超级管理员
        AdminAccount adminAccount = adminAccountMapper.selectById(accountId);
        if (adminAccount == null) {
            throw new BizException(ErrorCode.SYSTEM_RESOURCE_ADMIN_ACCOUNT_NOT_EXISTS);
        }
        if (adminAccount.getAdminRoleId() == RoleCode.SUPER_ADMIN.getCode().longValue()||
                adminAccount.getAdminRoleId() == RoleCode.COMPANY_SUPER_ADMIN.getCode().longValue()||
                adminAccount.getAdminRoleId() == RoleCode.COMPANY_ADMIN.getCode().longValue()) {
            return;
        }

        if (deptId != null) {
            // 检查部门是否存在
            LambdaQueryWrapper<DeptInfo> deptWrapper = new LambdaQueryWrapper<>();
            deptWrapper.eq(DeptInfo::getDeptId, deptId)
                    .eq(DeptInfo::getIsDel, 0);
            if (deptInfoMapper.selectCount(deptWrapper) == 0) {
                throw new BizException(ErrorCode.SYSTEM_RESOURCE_COMPANY_NOT_EXISTS);
            }
        } else {
            // 检查是否是 1，2，3，4
            if (adminAccount.getAdminRoleId() != RoleCode.SUPER_ADMIN.getCode().longValue() &&
                    adminAccount.getAdminRoleId() != RoleCode.COMPANY_SUPER_ADMIN.getCode().longValue() &&
                    adminAccount.getAdminRoleId() != RoleCode.COMPANY_ADMIN.getCode().longValue() &&
                    adminAccount.getAdminRoleId() != RoleCode.DEPT_SUPER_ADMIN.getCode().longValue()) {
                throw new BizException(ErrorCode.USER_PERMISSION_ERROR_ONLY_SUPER_ADMIN_COMPANY_SUPER_AMIN_COMPANY_ADMIN_DEPT_SUPER_ADMIN);
            }
        }



        // 是否拥有权限
        LambdaQueryWrapper<AdminDeptPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AdminDeptPermission::getDeptId, deptId)
                .eq(AdminDeptPermission::getAccountId, accountId)
                .eq(AdminDeptPermission::getIsDel, 0);
        if (adminDeptPermissionMapper.selectCount(wrapper) <= 0) {
            throw new BizException(ErrorCode.USER_DEPT_PERMISSION_ERROR);
        }
    }

}
